package top.yangguangmc.smart_scheduling;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Scanner;

public class IOManager {
    public static final Path rootPath = new File(System.getenv("APPDATA") + "\\yangguangMC\\" + SmartScheduling.TITLE).toPath();
    public static final File logFile = new File(rootPath.toFile().getAbsolutePath() + "\\logs\\latest.log");
    private static final Logger logger = LogManager.getLogger();

    static {
        logger.info("Creating %Appdata% directories...");
        Path p;
        try {
            p = Files.createDirectories(rootPath);
            if (p == null)
                throw new IOException("Failed to create directory " +
                        "because Files.createDirectories(rootPath) returns null.");
            logger.info("Successfully created directory at " + p);

            if (!logFile.exists()) {
                boolean b = logFile.createNewFile();
                if (!b) throw new IOException("Failed to create log file " +
                        "because File.createNewFile() returns false.");
                logger.info("Successfully created log file at " + logFile.getAbsolutePath());
            }
        } catch (IOException e) {
            logger.error("Failed to create AppData directory!", e);
        }

    }

    public final BufferedImage imageIconAddNewLine;
    public final BufferedImage imageIconCalendar;
    public final BufferedImage imageIconExit;
    public final BufferedImage imageIconRefresh;
    public final BufferedImage imageIconRemoveLine;
    public final BufferedImage imageIconSave;
    private final Scanner sc;

    public IOManager() throws IOException {
        logger.info("Loading IOManager...");
        logger.debug("Resource URL: " + IOManager.class.getResource("/log4j2.xml"));
        try {
            imageIconAddNewLine = ImageIO.read(Objects.requireNonNull(IOManager.class.getResource("/icons/icon-addNewLine.png")));
            imageIconCalendar = ImageIO.read(Objects.requireNonNull(IOManager.class.getResource("/icons/icon-calendar.png")));
            imageIconExit = ImageIO.read(Objects.requireNonNull(IOManager.class.getResource("/icons/icon-exit.png")));
            imageIconRefresh = ImageIO.read(Objects.requireNonNull(IOManager.class.getResource("/icons/icon-refresh.png")));
            imageIconRemoveLine = ImageIO.read(Objects.requireNonNull(IOManager.class.getResource("/icons/icon-removeLine.png")));
            imageIconSave = ImageIO.read(Objects.requireNonNull(IOManager.class.getResource("/icons/icon-save.png")));
        } catch (NullPointerException e) {
            throw new IOException(e);
        }
        sc = new Scanner(System.in);
        Thread thread = getConsoleScannerThread();
        thread.start();

    }

    @NotNull
    private Thread getConsoleScannerThread() {
        Thread thread = new Thread(() -> {
            while (true) {
                if (sc.hasNext()) {
                    String s = sc.nextLine();
                    s = s.trim();
                    if (s.isEmpty()) continue;
                    logger.info("Command Input >> " + s.toLowerCase());
                    if (s.equalsIgnoreCase("exit")
                            || s.equalsIgnoreCase("quit")
                            || s.equalsIgnoreCase("stop"))
                        SmartScheduling.getInstance().stop();
                    else if (s.equalsIgnoreCase("save")
                            || s.equalsIgnoreCase("save-all"))
                        SmartScheduling.getInstance().saveAll();
                    else if (s.equalsIgnoreCase("showConfigPath")) {
                        logger.info("Config path: \"" + rootPath + "\"");
                        try {
                            Runtime.getRuntime().exec("explorer.exe /select," + rootPath.toFile().getAbsolutePath());
                        } catch (IOException e) {
                            logger.error("Failed to open the path in explorer.exe.", e);
                        }
                    } else
                        logger.info("Invalid command: " + s);

                }
            }
        }, "ConsoleInputThread");
        thread.setDaemon(true);
        return thread;
    }

//    public void readDefaultExcel() {
//        String fileName = rootPath + "\\tables\\DefaultTable.xlsx";
//        EasyExcel.read(fileName, ExcelData.class, new DataListener()).sheet().doRead();
//
//    }

    public void writeObject(Object object, File file) throws IOException {
        try (ObjectOutputStream oos = new ObjectOutputStream(Files.newOutputStream(file.toPath()))) {
            oos.writeObject(object);
        }
    }

    public Object readObject(File file) throws IOException {
        try (ObjectInputStream ois = new ObjectInputStream(Files.newInputStream(file.toPath()))) {
            return ois.readObject();
        } catch (ClassNotFoundException e) {
            throw new IOException(e);
        }
    }

}
